﻿// Jinx AJAX Framework
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Core.Parsing.LexicalAnalysis;
using System.IO;

namespace Formality.FormalSystem.Parser
{
    public class GrammarLexer : LexerBuilder
    {
        public GrammarLexer(
            Terminals Terminals,
            PrecedenceRules PrecedenceRules,
            UnaryOperators Binders,
            UnaryOperators UnaryOperators)
        {
            foreach (var Rule in PrecedenceRules.Rules)
                Add(Terminals.OPERATOR,
                    Rule.Value.CanonicalSymbol.ToString(),
                    Rule.Key);

            Add(Terminals.COMMA, ",", ",");

            Add(Terminals.LEFT, "(", "(", "[");
            Add(Terminals.RIGHT, ")", ")", "]");
            Add(Terminals.BANG, "!", "!");
            Add(Terminals.THE, Operators.THE, "?");

            foreach (var Binder in Binders.Operators)
                Add(Terminals.BINDER, Binder.Value, Binder.Variants);

            foreach (var uOp in UnaryOperators.Operators)
                Add(Terminals.OPERATOR, uOp.Value, uOp.Variants);

            for (var c = 'a'; c <= 'z'; c++)
            {
                Add(Terminals.IDENT, c.ToString(), c.ToString());

                var d = char.ToUpper(c);
                Add(Terminals.IDENT, d.ToString(), d.ToString());
            }

            var Greek = new[] {
                new [] { "\u0393", "Ga", "Gamma" },
                new [] { "\u0394", "De", "Delta" },
                new [] { "\u0398", "Th", "Theta" },
                new [] { "\u039e", "Xi" },
                new [] { "\u03a1", "Pi" },
                new [] { "\u03a3", "Si", "Sigma" },
                new [] { "\u03a6", "Ph", "Phi" },
                new [] { "\u03a8", "Ps", "Psi" },
                new [] { "\u03a9", "Om", "Omega" },
                new [] { "\u03b1", "al", "alpha" },
                new [] { "\u03b2", "be", "beta" },
                new [] { "\u03b3", "ga", "gamma" },
                new [] { "\u03b4", "de", "delta" },
                new [] { "\u03b5", "ep", "epsilon" },
                new [] { "\u03b6", "ze", "zeta" },
                new [] { "\u03b7", "et", "eta" },
                new [] { "\u03b8", "th", "theta" },
                new [] { "\u03ba", "ka", "kappa" },
                new [] { "\u03bc", "mu" },
                new [] { "\u03be", "xi" },
                new [] { "\u03c0", "pi" },
                new [] { "\u03c1", "rh", "rho" },
                new [] { "\u03c3", "si", "sigma" },
                new [] { "\u03c4", "ta", "tau" },
                new [] { "\u03c5", "up", "upsilon" },
                new [] { "\u03c6", "ph", "phi" },
                new [] { "\u03c7", "ch", "chi" },
                new [] { "\u03c8", "ps", "psi" },
                new [] { "\u03c9", "om", "omega" },
            };

            foreach (var g in Greek)
                Add(Terminals.IDENT, g[0], g);
        }

        public override string ToString()
        {
            return NewLexer(new StringReader("")).ToString();
        }
    }
}
